package com.tool_stdy.dbPool;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Vector;

/**
 * Created by yan_li on 2017/1/12.
 */
public class PoolServiceImpl implements PoolServer {

    private static String jdbcDriver = "";
    private static String jdbcurl = "";
    private static String userName = "";
    private static String password = "";
    private static int initCount;
    //如果连接池不够,填充多少
    private static int stepSize = 1;
    private static int poolMaxSize;

    private static Vector<PoolConnection> poolConnecntons = new Vector<PoolConnection>();


    public PoolServiceImpl() {
        try {
            init();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void init() throws Exception {
        InputStream resourceAsStream = this.getClass().getResourceAsStream("db.properties");
        Properties pro = new Properties();
        pro.load(resourceAsStream);
        jdbcDriver = pro.getProperty("jdbc.asms.driverClassName");
        jdbcurl = pro.getProperty("jdbc.asms.url");
        userName = pro.getProperty("jdbc.asms.username");
        password = pro.getProperty("jdbc.asms.password");
        initCount = Integer.valueOf(pro.getProperty("jdbc.asms.minPoolSize"));
        poolMaxSize = Integer.valueOf(pro.getProperty("jdbc.asms.maxPoolSize"));
        //获取连接驱动
        Driver driver = (Driver) Class.forName(jdbcDriver).newInstance();
        //驱动注册
        DriverManager.registerDriver(driver);
        //创建物理连接数据库的对象放入这个方法中
        createConnections(initCount);
    }

    public PoolConnection getRelationConnection() {
        if (poolConnecntons.size() <= 0) {
            System.out.println("连接池没有对象");
            throw new RuntimeException("连接池没有对象");
        }

        PoolConnection connection = getConnection();
        while (connection == null) {
            //证明所有的连接都在被使用，所以此时需要往连接池中创建新的连接
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            connection = getConnection();
            if (connection != null) {
                break;
            }
            createConnections(stepSize);
        }
        return connection;
    }

    @Override
    public synchronized PoolConnection getConnection() {
        try {
            for (PoolConnection conn : poolConnecntons) {
                System.out.println(Thread.currentThread().getName()+"-->"+conn.hashCode()+"-----"+conn.isbusy());
                if (!conn.isbusy()) {
                    Connection connection = conn.getConnection();
                    //判断拿到的连接是否有效，内部做的事情是尝试操作下数据库看看是否能通
                    if (!connection.isValid(2000)) {
                        //此物理连接对象不能使用
                        Connection con = DriverManager.getConnection(jdbcurl, userName, password);
                        conn.setConnection(con);
                    }
                    conn.setIsbusy(true);
                    return conn;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 创建连接对象的方法
     *
     * @param count
     */
    @Override
    public synchronized void createConnections(int count) {
        for (int i = 0; i < count; i++) {
            if (poolMaxSize > 0 && (poolConnecntons.size() + count) > poolMaxSize) {
                System.out.println("连接上限");
                throw new RuntimeException("连接数量超过上限");
            }
            try {
                Connection connection = DriverManager.getConnection(jdbcurl, userName, password);
                PoolConnection pool = new PoolConnection(connection, false);
                poolConnecntons.add(pool);
                System.out.println(Thread.currentThread().getName() + "---" + poolConnecntons.size());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }


    }
}
